using Castle.Components.Pagination;
using Castle.MonoRail.Framework;
using NHibernate.Criterion;
using NhibernateDemoCore;
using NhibernateDemoMvc.Filters;
using NhibernateDemoMvc.ViewModel;
using Order=NHibernate.Criterion.Order;

namespace NhibernateDemoMvc.Controllers
{
    [Layout("Default")]
    [TransactionFilter]
    public class CustomerController : SmartDispatcherController
    {
        private const int ItemsPerPage = 20;

        public void Index()
        {
            RedirectToAction("Index", new { page = 1 });
        }

        public void Index(int page)
        {
            var factory = SessionFactoryAccessor.Factory;
            var session = factory.GetCurrentSession();

            var customers = session
                .CreateCriteria<Customer>()
                .AddOrder(Order.Asc("Name"))
                .SetMaxResults(ItemsPerPage)
                .SetFirstResult((page - 1)*ItemsPerPage)
                .Future<Customer>();

            var totalCustomers = session
                .CreateCriteria<Customer>()
                .SetProjection(Projections.RowCount())
                .FutureValue<int>();

            PropertyBag["Customers"] = new GenericCustomPage<Customer>(customers, page, ItemsPerPage, totalCustomers.Value);
        }

        [SkipFilter(typeof(TransactionFilter))]
        public void New()
        {
        }

        public void Add([DataBind("new")]NewCustomerCommand command)
        {
            var factory = SessionFactoryAccessor.Factory;
            var session = factory.GetCurrentSession();

            var customer = new Customer
                               {
                                   Name = command.Name,
                                   BillingAddress = new Address
                                                        {
                                                            Line1 = command.Line1,
                                                            Line2 = command.Line2,
                                                            City = command.City,
                                                            State = command.State,
                                                            Zip = command.Zip
                                                        }
                               };

            session.Save(customer);
            RedirectToAction("Index");
        }

        public void Edit(long customerId)
        {
            var factory = SessionFactoryAccessor.Factory;
            var session = factory.GetCurrentSession();

            var customer = session.Get<Customer>(customerId);
            PropertyBag["Customer"] = customer;
        }

        public void Update([DataBind("customer")]ExistingCustomerCommand command)
        {
            var factory = SessionFactoryAccessor.Factory;
            var session = factory.GetCurrentSession();

            var customer = session.Get<Customer>(command.Id);
            customer.Name = command.Name;
            customer.BillingAddress.Line1 = command.Line1;
            customer.BillingAddress.Line2 = command.Line2;
            customer.BillingAddress.City = command.City;
            customer.BillingAddress.State = command.State;
            customer.BillingAddress.Zip = command.Zip;

            RedirectToAction("Index");
        }

        public void Remove(long customerId)
        {
            var factory = SessionFactoryAccessor.Factory;
            var session = factory.GetCurrentSession();

            var customer = session.Load<Customer>(customerId);
            session.Delete(customer);
            RedirectToReferrer();
        }
    }
}